<?php
class PhotoController extends Controller
{
	public function actionUpload()
	{
		$transaction = Yii::app()->db->begintransaction();
		try {
			if(!isset($_POST['place_id'], $_POST['uid'], $_FILES['img'])){
				throw new PlatwoException(1100, 'Need variable place_id, uid, imgName');
			}
			$place_id = $_POST['place_id'];
			$uid = $_POST['uid'];
			if(isset($_POST['albumId'])) {
				$album = Gallery::model()->findByPk($_POST['albumId']);
				if($album == null){
					throw new PlatwoException(9999, 'album not found');
				}
				$photo_group = $album->photo_group;
			}
			else {
				$site = Site::model()->findByPk($place_id);
				if($site == null){
					throw new PlatwoException(9999, 'site not found');
				}
				$photo_group = $site->photo_group;
			}
			$photoGroup = PhotoGroup::model()->findByPk($photo_group);
			if($photoGroup == null) {
				$photoGroup = new PhotoGroup();
				$photoGroup->photo_count = 0;
				if(!$photoGroup->save()) {
					throw new PlatwoException(1201, 'Save photo Group Error.');
				}
				$site->photo_group = $photoGroup->photo_group_id;
				if(!$site->save()) {
					throw new PlatwoException(1202, 'Update Place photo_group Error.');
				}
			}
				
			$data = array();
			$photo = new Photo();
			$data['photo_group'] = $photo->photo_group = $photoGroup->photo_group_id;
 			
			if(Photo::model()->count("photo_group=:photo_group", array(':photo_group'=> $photo_group)) != 0) {
				$criteria = new CDbCriteria();
				//$criteria->select = "seq";
				$criteria->condition = "photo_group=:photo_group";
				$criteria->order = "seq DESC";
				$criteria->params = array(':photo_group'=> $photo_group);
				$seq = 0;
				$buffer = Photo::model()->find($criteria);
				if($buffer != null) { $photo->seq = $buffer->seq + 1; }
			}
			if(!$photo->save()) {
				throw new PlatwoException(1201, 'Save Photo Error.');
			}
			
			$path = 'photos/'.$photo->photo_id.'.jpg';
			$data['photo_url'] = $photo->photo_url = $photo->photo_id.'.jpg';
			if(!$photo->save()) {
				throw new PlatwoException(9999, 'Update PhotoName Error.');
			}
			
			$count = Photo::model()->count("photo_group=:photo_group", array(':photo_group'=> $photoGroup->photo_group_id));
			$photoGroup->photo_count = $count;
			if(!$photoGroup->save()) {
				throw new PlatwoException(9999, 'Update Photo Count Failed.');
			}
			
			$data['photo_id'] = $data['id'] = $photo->photo_id.'.jpg';
			$data['seq'] = $photo->seq;
			$resp = array(
				'errorCode'=> 0,
				'errorMessage' => '',
				'data'=> $data,
			);
			
			if(!move_uploaded_file($_FILES['img']['tmp_name'], $path) && !chmod( $path, 0777 )){
				throw new PlatwoException(9999, 'Upload Failed.');
			}
			
			$image = new Imagick($path);
			$image->setImageColorspace(255);
			$image->setCompression(Imagick::COMPRESSION_JPEG);
			$image->setCompressionQuality(60);
			$image->setImageFormat('jpeg');
			
			if(!$image->writeImage($path)) {
				throw new PlatwoException(9999, 'Convertto jpg failed.');
			}
			$image->clear();
			$image->destroy();
			
			$transaction->commit();
			echo CJSON::encode($resp);
		} catch(PlatwoException $e) {
			$transaction->rollback();
			echo $e->toJSON();
		}
	}
	
	public function actionDeleteAll()
	{
		Photo::model()->deleteAll(TRUE);
		PhotoGroup::model()->deleteAll(TRUE);
		Gallery::model()->deleteAll(TRUE);
	}
	
	public function actionGetPhoto()
	{
		$uid = 83;
		$fields = array('photo_id', 'photo_url', 'photo_time', 'caption', 'comments', 'like');
		if(isset($_GET['fields'])) {
			$fields = explode(',', $_GET['fields']);
		}
		try {
			if(!isset($_GET['id'])) {
				throw new PlatwoException(9999, 'need property id');
			}
			$photo = $this->getPhoto($_GET['id'], $fields);
			if($photo == null) {
				throw new PlatwoException(9999, 'not found photo');
			}
			echo CJSON::encode($photo);
		} catch(PlatwoException $e) {
			echo $e->toJSON();
		}
	}
	
	public function actionGetPhotoPrev()
	{
		$fields = array('photo_id', 'photo_url', 'photo_time', 'caption', 'comments', 'like');
		try {
			if(!isset($_GET['id'])) {
				throw new PlatwoException(9999, 'need property id');
			}
			$photo = $this->getPhoto($_GET['id'], $fields);
			if($photo == null) {
				throw new PlatwoException(9999, 'not found photo');
			}
			echo CJSON::encode($photo);
		} catch(PlatwoException $e) {
			echo $e->toJSON();
		}
	}
	
	public function actionGetPhotoNext()
	{
		$fields = array('photo_id', 'photo_url', 'photo_time', 'caption', 'comments', 'like');
		try {
			if(!isset($_GET['id'])) {
				throw new PlatwoException(9999, 'need property id');
			}
			$photo = Photo::model()->findByPk($_GET['id']);
			if($photo == null) {
				throw new PlatwoException(9999, 'not found photo');
			}
			$photo = $this->getPhoto($_GET['id'], $fields);
			echo CJSON::encode($photo);
		} catch(PlatwoException $e) {
			echo $e->toJSON();
		}
	}
	
	public function actionMoveGallery()
	{
		$transaction = Yii::app()->db->begintransaction();
		try {
			if(!isset($_GET['photo_id'], $_GET['gallery_id'])) {
				throw new Exception(9999, "Need parameters photo_id, gallery_id");
			}
			$photo = Photo::model()->findByPk($_GET['photo_id']);
			$oldGroupId = $photo->photo_group;
			$gallery = Gallery::model()->findByPk($_GET['gallery_id']);
			$photo->photo_group = $gallery->photo_group;
			$buffer = Photo::model()->findByAttributes(array('photo_group'=> $photo->photo_group),
				array('order'=> 'seq DESC')
			);
			$seq = ($buffer == null) ? 0: $buffer->seq + 1;
			$photo->seq = $seq;
			if(!$photo->save()){
				throw new Exception(9999, "Can't save photo");
			}
			if(!$this->updateGroupPhoto($oldGroupId) || !$this->updateGroupPhoto($gallery->photo_group)){
				throw new Exception(9999, "Can't update photo count");
			}
			$transaction->commit();
			echo CJSON::encode($photo->getAttributes());
		} catch(PlatwoException $e) {
			$transaction->rollback();
			echo $e->toJSON();
		}
	}
	
	public function actionMovePhotos()
	{
		$transaction = Yii::app()->db->beginTransaction();
		try {
			if(!isset($_POST['photo_ids'], $_POST['gallery_id'])) {
				throw new Exception(9999, "Need parameters photo_ids, gallery_id");
			}
			$gallery = Gallery::model()->findByPk($_POST['gallery_id']);
			if($gallery == null) {
				throw new Exception(9999, "Not found gallery");
			}
			
			$first = Photo::model()->findByAttributes(array("photo_group"=> $gallery->photo_group), array("order"=> "seq DESC"));
			if($first == null) {
				$firstSeq = 0;
			}
			else {
				$firstSeq = $first->seq + 1;
			}
			$expression = '';
			$params = array();
			foreach($_POST['photo_ids'] as $key => $value) {
				$expression .= " WHEN ".$value." THEN :photo_id_{$value}";
				$params[":photo_id_{$value}"] = $key + $firstSeq;
			}
			$expression .= ' END ';
			if(!Photo::model()->updateByPk(
					$_POST['photo_ids'],
					array("photo_group"=> $gallery->photo_group, 'seq'=> new CDbExpression("CASE photo_id".$expression)),
					"", $params)){
				throw new PlatwoException(9999, 'move photos failed.');
			}
			$transaction->commit();
		} catch(PlatwoException $e) {
			$transaction->rollback();
			$e->toJSON();
		}
	}
	
	public function actionLike()
	{
		$transaction = Yii::app()->db->begintransaction();
		try {
			if(!isset($_GET['like_action'], $_GET['photo_id'], $_GET['uid'])) {
				throw new PlatwoException(9999, 'Need parameters like_action, photo_id');
			}
			$uid = $_GET['uid'];
			$likeAction = ($_GET['like_action'] === true || $_GET['like_action'] === "true") ? true: false;
			$photo = Photo::model()->findByPk($_GET['photo_id']);
			if($photo == null) {
				throw new PlatwoException(9999, 'Not found photo.');
			}
			$likeGroup = LikeGroup::model()->findByPk($photo->like_id);
			if($likeGroup == null) {
				$likeGroup = new LikeGroup();
				if(!$likeGroup->save()) {
					throw new PlatwoException(9999, 'Can not create photo_group.');
				}
				$photo->like_id = $likeGroup->like_group_id;
				if(!$photo->save()) {
					throw new PlatwoException(9999, 'Can not update photo_group.');
				}
			}
			$like = Like::model()->findByAttributes(array('like_group'=> $photo->like_id, 'uid'=> $uid));
			if($likeAction == true) {
				if($like == null) {
					$like = new Like();
					$like->uid = $uid;
					$like->like_group = $photo->like_id;
					if(!$like->save()) {
						throw new PlatwoException(9999, 'Can not add like.');
					}
				}
			}
			else {
				if($like != null) {
					if(!$like->delete()) {
						throw new PlatwoException(9999, 'Can not delete like.');
					}
				}
			}
			$count = Like::model()->count("like_group=:id", array(':id'=> $likeGroup->like_group_id));
			$likeGroup->like_count = $count;
			if(!$likeGroup->save()) {
				throw new PlatwoException(9999, 'Can not update like group.');
			}
			$transaction->commit();
			$resp = array();
			$resp = $photo->getAttributes();
			$resp['liked'] = $likeAction;
			$resp['likes'] = $likeGroup->like_count;
			echo CJSON::encode($resp);
		} catch(PlatwoException $e) {
			$transaction->rollback();
			echo $e->toJSON();
		}
	}
	
	public function actionAddComment()
	{
		$transaction = Yii::app()->db->begintransaction();
		try {
			if(!isset($_GET['text'], $_GET['photo_id'], $_GET['uid'])) {
				throw new PlatwoException(9999, 'Need parameters text, photo_id, uid');
			}
			$uid = $_GET['uid'];
			$photo = Photo::model()->findByPk($_GET['photo_id']);
			if($photo == null) {
				throw new PlatwoException(9999, 'Not found photo.');
			}
			$commentGroup = CommentGroup::model()->findByPk($photo->comment_group);
			if($commentGroup == null) {
				$commentGroup = new CommentGroup();
				if(!$commentGroup->save()) {
					throw new PlatwoException(9999, 'Can not create comment_group.');
				}
				$photo->comment_group = $commentGroup->id;
				if(!$photo->save()) {
					throw new PlatwoException(9999, 'Can not update comment_group in photo.');
				}
			}
			$comment = new Comment();
			$comment->comment_group = $commentGroup->id;
			$comment->uid = $uid;
			$comment->comment_text = $_GET['text'];
			if(!$comment->save()) {
				throw new PlatwoException(9999, 'Can not add comment in photo.');
			}
			if(!$comment->refresh()) {
				throw new PlatwoException(9999, 'Can not refresh comment.');
			}
			$count = Comment::model()->count("comment_group=:id", array(':id'=> $comment->comment_group));
			$commentGroup->count = $count;
			if(!$commentGroup->save()) {
				throw new PlatwoException(9999, 'Can not update like group.');
			}
			$transaction->commit();
			$resp = array();
			$resp = $comment->getAttributes();
			$account = Account::model()->findByPk($resp['uid']);
			$resp['from'] = $account->getAttributes(array('uid', 'name'));
			//$resp['count'] = $commentGroup->count;
			echo CJSON::encode($resp);
		} catch(PlatwoException $e) {
			$transaction->rollback();
			echo $e->toJSON();
		}
	}
	
	public function actionUpdateCaption()
	{
		if(!isset($_GET['photo_id'], $_GET['caption'])) {
			$e = new PlatwoException(9999, "Need parameters photo_id, caption");
			echo $e->toJSON();
		}
		$photo = $this->updateCaption($_GET['photo_id'], $_GET['caption']);
		if(!$photo) {
			$e = new PlatwoException(9999, "Can't update photo caption");
			echo $e->toJSON();
		}
		echo CJSON::encode($photo->getAttributes(array('photo_id', 'caption')));
	}
	
	public function actionDeletePhotos()
	{
		$transaction = Yii::app()->db->begintransaction();
		try {
			if(!isset($_POST['photos'])) {
				throw new PlatwoException(9999, "Need parameters photos");
			}
			if(!Photo::model()->deleteByPk($_POST['photos'])) {
				throw new PlatwoException(9999, "Can't delete photos");
			}
			$transaction->commit();
		}
		catch(PlatwoException $e) {
			$transaction->rollback();
			echo $e->toJSON();
		}
	}
	
	/********** internal function **********/
	
	protected function getPhoto($id, $fields){
		$uid = 83;
		$photo = Photo::model()->findByPk($id);
		if($photo == null) {
			return null;
		}
		$buffer = array();
		foreach($fields as $key => $value) {
			if($photo->hasAttribute($value)) { $buffer[$value] = $photo->getAttribute($value); }
		}
		if(in_array('comments', $fields)) {
			$comments = Comment::model()->findAllByAttributes(array('comment_group'=> $photo->comment_group), array(
					'offset'=> 0,
					'limit'=> 7,
					'order'=> 'comment_time DESC'
					));
			$count = Comment::model()->countByAttributes(array('comment_group'=> $photo->comment_group));
			$buffer['comments']['count'] = $count;
			$buffer['comments']['data'] = array();
			foreach($comments as $key => $comment) {
				$likeGroup = LikeGroup::model()->findByPk($comment->like);
				if($likeGroup == null) {
					$liked = false;
					$likes = 0;
				}
				else {
					$liked = Like::model()->count("like_group=:like_group AND uid=:uid", array(':like_group'=> $comment->like, ':uid'=> 83)) == 0 ? false: true;
					$likes = $likeGroup->like_count;
					$buffer['comments']['data'][$key]['test']['group'] = $likeGroup->getAttributes();
					$buffer['comments']['data'][$key]['test']['likee'] = Like::model()->count("like_group=:like_group AND uid=:uid", array(':like_group'=> $comment->like, ':uid'=> 83));
				}
				$buffer['comments']['data'][$key] = $comment->getAttributes();
				$account = Account::model()->findByPk($comment->uid);
				$buffer['comments']['data'][$key]['from'] = $account->getAttributes(array('name', 'uid'));
				// uid example
				$buffer['comments']['data'][$key]['liked'] = $liked;
				$buffer['comments']['data'][$key]['likes'] = $likes;
			}
		}
		if(in_array('like', $fields)) {
			if($photo->like_id == null || $photo->like_id == 0) {
				$count = 0;
				$buffer['liked'] = false;
				$buffer['likes'] = 0;
			}
			else {
				$count = Like::model()->count("like_group=:id AND uid=:uid", array(':id'=> $photo->like_id, 'uid'=> $uid));
				$buffer['liked'] = ($count > 0) ? true: false;
				$buffer['likes'] = Like::model()->count("like_group=:id", array(':id'=> $photo->like_id));
			}
		}
		
		/* fixed from test place (place_id: 1, place_name: 'TestPlace') */
		$buffer['from'] = array('id'=> 1, 'name'=> 'TestPlace');
		
		return $buffer;
	}
	
	protected function updateCaption($id, $caption)
	{
		$photo = Photo::model()->findByPk($id);
		if($photo == null) {
			return false;
		}
		$photo->caption = $caption;
		if(!$photo->save()) {
			return false;
		}
		return $photo;
	}
	
	protected function updateGroupPhoto($id)
	{
		$group = PhotoGroup::model()->findByPk($id);
		$count = Photo::model()->count("photo_group=:id", array(':id'=> $id));
		$group->photo_count = $count;
		return $group->save();
	}
	
	protected function updateLikeGroup($id)
	{
		$group = LikeGroup::model()->findByPk($id);
		$count = Like::model()->count("like_group=:id", array(':id'=> $id));
		$group->like_count = $count;
		return $group->save();
	}
}